/**
 * created by dqn 2018/3/7 19:26
 */

package main.service.impl;

import main.entity.Song;
import main.repository.SongRepository;
import main.service.SongService;
import main.util.MD5Util;
import main.util.Paths;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SongServiceImpl implements SongService {
    @Autowired
    SongRepository songRepository;
    @Autowired
    MD5Util md5Util;

    @Override
    public Song getSongById(int pk) {
        return songRepository.getSongByPk(pk);
    }

    @Override
    public Map<String,List<Song>> getSongsByContains(String key) {
//        return songRepository.getSongsByNameContainsOrLyricContains(key, key).orElse(new ArrayList<>());
        Map<String,List<Song>> map = new HashMap<>();
        List<Song> nameSong = songRepository.getSongsByNameContains(key).orElse(new ArrayList<>());
        List<Song> lyricSong = songRepository.getSongsByLyricContains(key).orElse(new ArrayList<>());
        List<Song> singerSong = songRepository.getSongsBySingerContains(key).orElse(new ArrayList<>());
        map.put("name",nameSong);
        map.put("lyric",lyricSong);
        map.put("singer",singerSong);
        return map;
    }

    @Override
    public Map<String, List<String>> getSongCategories() {
        List<String> styles = getAllSongs().stream().map(song -> song.getStyle()).distinct().collect(Collectors.toList());
        List<String> languages = getAllSongs().stream().map(song -> song.getLanguage()).distinct().collect(Collectors.toList());
        Map<String, List<String>> result = new HashMap<>();
        result.put("style", styles);
        result.put("language", languages);
        return result;
    }

    @Override
    public List<Song> getAllSongs() {
        List<Song> songs = new ArrayList<>();
        songRepository.findAll().forEach(song -> songs.add(song));
        return songs;
    }

    @Override
    public Song uploadSong(HttpSession session, Song data, MultipartFile song, MultipartFile image) {
        String songFileName = md5Util.getEncodedMD5(song.getOriginalFilename()+song.hashCode())
                + "." + song.getOriginalFilename()
                .substring(song.getOriginalFilename().indexOf(".") + 1,
                        song.getOriginalFilename().length());
        songFileName = Paths.UPLOAD_DIR + Paths.SONG_DIR + "/" + songFileName;
        String path = session.getServletContext().getRealPath(songFileName);

        try {
            song.transferTo(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        String imageFileName = md5Util.getEncodedMD5(image.getOriginalFilename()+image.hashCode())
                + "." + image.getOriginalFilename()
                .substring(image.getOriginalFilename().indexOf(".") + 1,
                        image.getOriginalFilename().length());

        imageFileName = Paths.UPLOAD_DIR + Paths.IMAGE_DIR + "/" + imageFileName;

        String imagePath = session.getServletContext().getRealPath(imageFileName);
        try {
            image.transferTo(new File(imagePath));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        data.setFileUri(songFileName);
        data.setImgUri(imageFileName);
        String[] name = song.getOriginalFilename().substring(0, song.getOriginalFilename().indexOf(".")).split("-");
        data.setName(name[1]);
        data.setSinger(name[0]);
        data.setUpload(new Date(System.currentTimeMillis()));

        if (data.getName() == null || data.getName().equals("")) {
            data.setName(song.getOriginalFilename().split(".")[0]);
        }
        return songRepository.save(data);
    }

    @Override
    public Song getSongByName(String name) {
        return songRepository.getSongsByName(name).orElse(null);
    }

    @Override
    public Page<Song> getSongsInPageByStyle(String style, Pageable pageable) {
        return songRepository.getSongsByStyle(style, pageable);
    }

    public  Page<Song> getSongsInPageByLanguage(String language, Pageable pageable) {
        return songRepository.getSongsByLanguage(language, pageable);
    }

    @Override
    public Page<Song> getAll(Pageable pageable) {
        return songRepository.findAll(pageable);
    }

    @Override
    public List<Song> getAllByClickLimitedTo(int size) {
        return songRepository
                .findAllByPkAfter(0, PageRequest.of(0, size, Sort.Direction.DESC, "click", "name"))
                .getContent();
    }

    @Override
    public Song updateSong(Song song) {
        return songRepository.save(song);
    }

    @Override
    public boolean deleteById(int id) {
        try {
            songRepository.deleteById(id);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public List<Song> getNewSongsLimit(int limit) {
        return songRepository
                .findAllByPkAfter(0,PageRequest.of(0,limit,Sort.Direction.DESC,"upload","name"))
                .getContent();
    }

}
